package com.zzzzzz.app.topic.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.apache.shiro.authz.annotation.RequiresUser;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.zzzzzz.app.account.model.po.User;
import com.zzzzzz.app.account.service.UserManager;
import com.zzzzzz.app.topic.model.bo.CommentBo;
import com.zzzzzz.app.topic.model.bo.json.CommentDeleteJsonBo;
import com.zzzzzz.app.topic.model.bo.json.CommentJsonBo;
import com.zzzzzz.app.topic.model.bo.json.CommentJsonListBo;
import com.zzzzzz.app.topic.model.bo.json.CommentReplyJsonBo;
import com.zzzzzz.app.topic.model.po.Comment;
import com.zzzzzz.app.topic.service.CommentManager;
import com.zzzzzz.core.controller.BaseController;
import com.zzzzzz.core.exception.SystemException;
import com.zzzzzz.core.exception.ZzzzzzException;

@Controller
public class CommentController extends BaseController {

	@Resource
	private UserManager userManager;
	
	@Resource
	private CommentManager commentManager;

	@RequiresUser
	@RequestMapping(value = "/user/add_comment", method = RequestMethod.GET)
	public @ResponseBody String addComment(Model model, HttpServletRequest request,
			@RequestParam(value="topic_id", required=true) Long topicId,
			@RequestParam(value="content", required=true) String content) throws Exception {
		try{
			long userId = userManager.findCurrentUserId();
			Date now = new Date();
			Comment comment = commentManager.add(userId, topicId, content, now, Long.valueOf(0));

			User user = userManager.findById(userId);
			String userName = user.getUsername();
    		String contextPath = request.getContextPath();
			CommentBo commentBo = new CommentBo(comment);
			commentBo.setCreateBy(userName);
			String html = getParentCommentHtml(commentBo, contextPath, true);
			return html;
		}catch(Exception e) {
			logger.error(e.getMessage(), e);
			throw e;
		}
	}

	@RequiresUser
	@RequestMapping(value = "/user/add_reply", method = RequestMethod.GET)
	public @ResponseBody CommentReplyJsonBo addReply(Model model, HttpServletRequest request,
			@RequestParam(value="topic_id", required=true) Long topicId,
			@RequestParam(value="parent_id", required=true) Long parentId,
			@RequestParam(value="content", required=true) String content) throws Exception {
		try{
			long userId = userManager.findCurrentUserId();
			Date now = new Date();
			Comment comment = commentManager.add(userId, topicId, content, now, parentId);

			User user = userManager.findById(userId);
			String userName = user.getUsername();
    		String contextPath = request.getContextPath();
			CommentBo commentBo = new CommentBo(comment);
			commentBo.setCreateBy(userName);
			String html = getChildCommentHtml(commentBo, contextPath);
			CommentReplyJsonBo commentReplyJsonBo = new CommentReplyJsonBo(parentId, html);
			return commentReplyJsonBo;
		}catch(Exception e) {
			logger.error(e.getMessage(), e);
			throw e;
		}
	}

	@RequestMapping(value = "/user/delete_comment", method = RequestMethod.GET)
	public @ResponseBody CommentDeleteJsonBo deleteComment(Model model, HttpServletRequest request,
			@RequestParam(value="comment_id", required=true) Long commentId, 
			@RequestParam(value="is_parent", required=true) Boolean isParent) throws Exception {
		try {
			commentManager.delete(commentId);
			if(isParent) {
				List<Comment> childCommentList = commentManager.findAllCommentsByParentId(commentId);
				for(Comment cc : childCommentList) {
					commentManager.delete(cc.getCommentId());
				}
			}
			CommentDeleteJsonBo commentDeleteJsonBo = new CommentDeleteJsonBo(commentId, isParent);
			return commentDeleteJsonBo;
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			throw e;
		}
		
	}
	
    @RequestMapping(value = "/user/retrieve_comments", method = RequestMethod.POST)
    public @ResponseBody CommentJsonListBo retrieveComments(Model model, HttpServletRequest request,
    		@RequestParam(value="topic_id", required=true) Long topicId,
    		@RequestParam(value="cur_showing_no", required=true) Integer curShowingNo,
    		@RequestParam(value="offset", required=true) Integer offset) throws Exception {
    	try{
    		int total = commentManager.findCountByTopicId(topicId);
    		int start = curShowingNo;
    		int end = curShowingNo + offset;
        	if(end >= total) {
        		end = total;
        	}
    		String contextPath = request.getContextPath();
    		
        	String showingStatus = "";
        	if(total == 0) {
        		showingStatus += "No comment yet"; 
        	}else {
        		showingStatus += "Showing " + end + " of " + total + " comments";
        	}
    		return populateCommentJsonList(topicId, start, offset, total, contextPath, showingStatus);
    	}catch(Exception e) {
			logger.error(e.getMessage(), e);
			throw e;
		}
    }
	
    private CommentJsonListBo populateCommentJsonList(long topicId, int start, int offset, int total, String contextPath, String showingStatus) throws SystemException, ZzzzzzException {
    	List<CommentJsonBo> commentJsonBos = new ArrayList<CommentJsonBo>();
    	List<CommentBo> parentCommentBos = commentManager.findByTopicId(topicId, false, start, offset, true, 0, Integer.MAX_VALUE);
    	
    	for(CommentBo pc : parentCommentBos) {
    		boolean closeStatus = pc.getCloseStatus();
    		if(!closeStatus) {
				String html = getParentCommentHtml(pc, contextPath, true);
				
			    CommentJsonBo commentJsonBo = new CommentJsonBo(html);
			    commentJsonBos.add(commentJsonBo);
    		}
    	}

    	CommentJsonListBo commentJsonListBo = new CommentJsonListBo(commentJsonBos, total, showingStatus);
    	return commentJsonListBo;
    }
    
    private String getParentCommentHtml(CommentBo parentCommentBo, String contextPath, boolean isIncludeChildren) throws ZzzzzzException, SystemException {
    	long commentId = parentCommentBo.getCommentId();
		String content = parentCommentBo.getContent();
		Date createDate = parentCommentBo.getCreateDate();
		String displayDate = format.format(createDate);
		long actorId = parentCommentBo.getUserId();
		boolean isOwner = false;
		if(isSignedIn()) {
			User currentUser = userManager.findCurrentUser();
			long currentUserId = currentUser.getUserId();
			isOwner = (currentUserId == actorId) ? true : false;
		}
		String userName = parentCommentBo.getCreateBy();
		String userPic = contextPath + "/res/images/fb_avatar.png";
		String profileURL = contextPath + "/profile?id=" + actorId;
    	
		String html = "<li class=\"comment-entry level1\" data-comment-id=\"" + commentId + "\" data-comment-is-parent=\"true\">" + 
			"<div class=\"comment-entry-inner\">" + 
			"<a href=\"" + profileURL + "\"><img class=\"avatar\" src=\"" + userPic +"\"></a>" + 
			"<div class=\"comment-content-wrap\">" + 
			"<div class=\"comment-content\" data-comment-dom-id=\"entry-content\">" + 
			"<a class=\"username\" href=\"" + profileURL + "\">" + userName + "</a>" + 
			"<span>" + content + "</span>" + 
			"<div class=\"actions\"><span class=\"timestamp\">" + displayDate + "</span> - <a href=\"#replay_link\">Reply</a></div>";
    	
		if(isOwner) {
			html += "<div style=\"display: none;\" class=\"options\" data-comment-dom-id=\"entry-options\"><a href=\"#\">X</a></div>";
		}	
		
		html += "</div><div class=\"comment-reply-container\" data-comment-dom-id=\"reply-container\">" + 
			"<ul data-comment-dom-id=\"child-entry-container\">";
    	
		if(isIncludeChildren) {
	    	List<CommentBo> childCommentBoList = parentCommentBo.getChildCommentBoList();
	    	for(CommentBo cb : childCommentBoList) {
	    		boolean closeStatus = cb.getCloseStatus();
	    		if(!closeStatus) {
					html += getChildCommentHtml(cb, contextPath);
	    		}
	    	}
		}
			
		html += "</ul>";
		html += getReplyFormHtml(contextPath);
		html += "</div></div></div></li>";
    	
    	return html;
    }

    private String getChildCommentHtml(CommentBo commentBo, String contextPath) throws ZzzzzzException, SystemException {
    	long commentId = commentBo.getCommentId();
		String content = commentBo.getContent();
		Date createDate = commentBo.getCreateDate();
		String displayDate = format.format(createDate);
		long actorId = commentBo.getUserId();
		boolean isOwner = false;
		if(isSignedIn()) {
			User currentUser = userManager.findCurrentUser();
			long currentUserId = currentUser.getUserId();
			isOwner = (currentUserId == actorId) ? true : false;
		}
		String userName = commentBo.getCreateBy();
		String userPic = contextPath + "/res/images/fb_avatar.png";
		String profileURL = contextPath + "/profile?id=" + actorId;
		
//		data-comment="{ "id" : 200, "is_parent" : true }"
		
    	String html = "<li class=\"comment-entry level2\" data-comment-id=\"" + commentId + "\" data-comment-is-parent=\"false\">" + 
			"<div class=\"comment-entry-inner\">" + 
			"<a href=\"" + profileURL + "\"><img class=\"avatar\" src=\"" + userPic +"\"></a>" + 
			"<div class=\"comment-content-wrap\">" + 
			"<div class=\"comment-content\" data-comment-dom-id=\"entry-content\">" + 
			"<a class=\"username\" href=\"" + profileURL + "\">" + userName + "</a>" + 
			"<span>" + content + "</span>" + 
			"<div class=\"actions\"><span class=\"timestamp\">" + displayDate + "</span> - <a href=\"#replay_link\">Reply</a></div>";
		
		if(isOwner) {
			html += "<div style=\"display: none;\" class=\"options\" data-comment-dom-id=\"entry-options\"><a href=\"#\">X</a></div>";
		}
		html += "</div></div></div></li>";
		return html;
    }
    
    private String getReplyFormHtml(String contextPath) {
    	String html = "<div class=\"comment-entry level2\" data-comment-dom-id=\"reply-form-container\" style=\"display: none;\">" + 
			"<div class=\"comment-entry-inner\">" + 
			"<img class=\"avatar\" data-comment-dom-id=\"avatar\" src=\"" + contextPath + "/res/images/fb_avatar.png\">" + 
			"<div data-comment-dom-id=\"reply-textarea-container\" style=\"margin: 0 0 0 40px\">" + 
			"<div class=\"comment-textarea-outer\">" + 
			"<form action=\"" + contextPath + "/user/add_reply\" method=\"post\" data-comment-dom-id=\"reply-form\">" + 
			"<textarea style=\"height: 28px;\" placeholder=\"Add a reply...\" data-comment-dom-id=\"reply-textarea\"></textarea>" + 
			"</form>" + 
			"</div>" + 
			"<div class=\"tip\" data-comment-dom-id=\"reply-tip\">Press Enter to post your comment.</div>" + 
			"</div></div></div>";
    	return html;
    }
	
	private static Logger logger = Logger.getLogger(CommentController.class);
	
}

